<template>
  <transition name="v-message-fade" @after-leave="handleAfterLeave">
    <div
      :class="[
        'v-message',
        'flex',
        type ? `el-message--${type}` : '',
        center ? 'is-center' : '',
        showClose ? 'is-closable' : '',
      ]"
      v-show="visible"
      role="alert"
      :style="positionStyle"
      @mouseenter="clearTimer"
      @mouseleave="startTimer"
    >
      <i :class="typeClass"></i>
      <slot>
        <p v-if="!dangerouslyUseHTMLString" class="v-message__content">
          {{ message }}
        </p>
        <p v-else v-html="message" class="v-message__content"></p>
      </slot>
      <i
        v-if="showClose"
        class="v-message__icon v-icon-close"
        @click="close"
      ></i>
    </div>
  </transition>
</template>
<script>
const typeMap = {
  success: "success",
  info: "info",
  warning: "warning",
  error: "error",
};
export default {
  name: "message",
  data() {
    return {
      visible: false,
      message: "",
      duration: 3000,
      type: "info",
      onClose: null,
      showClose: false,
      closed: false,
      verticalOffset: 20,
      timer: null,
      dangerouslyUseHTMLString: false,
      center: false,
    };
  },
  computed: {
    typeClass() {
      return this.type ? `v-message__icon v-icon-${typeMap[this.type]}` : "";
    },
    positionStyle() {
      return {
        top: `${this.verticalOffset}px`,
      };
    },
  },

  watch: {
    closed(newVal) {
      if (newVal) {
        this.visible = false;
      }
    },
  },

  methods: {
    handleAfterLeave() {
      this.$destroy(true);
      this.$el.parentNode.removeChild(this.$el);
    },

    close() {
      this.closed = true;
      if (typeof this.onClose === "function") {
        console.log('==============')
        this.onClose(this);
      }
    },

    clearTimer() {
      clearTimeout(this.timer);
    },

    startTimer() {
      if (this.duration > 0) {
        this.timer = setTimeout(() => {
          if (!this.closed) {
            this.close();
          }
        }, this.duration);
      }
    },
    keydown(e) {
      if (e.keyCode === 27) {
        // esc关闭消息
        if (!this.closed) {
          this.close();
        }
      }
    },
  },
  mounted() {
    this.startTimer();
    document.addEventListener("keydown", this.keydown);
  },
  beforeDestroy() {
    document.removeEventListener("keydown", this.keydown);
  },
};
</script>
<style lang="less" scoped>
.v-message {
  min-width: 380px;
  box-sizing: border-box;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  position: fixed;
  left: 50%;
  top: 20px;
    padding: 15px;
  transform: translateX(-50%);
  background-color: #edf2fc;
  overflow: hidden;
  transition: opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;
  z-index: 1000;
  &.is-center{
    justify-content: center;
  }
  &.is-closable {
    .v-message__content {
      margin-right: 25px;
    }
  }
  .v-message__icon {
    display: inline-block;
    width: 20px;
    height: 20px;
    background-size: contain;
    background-repeat: no-repeat;
    &.v-icon-info {
      background-image: url("./icon/info.png");
    }
    &.v-icon-error {
      background-image: url("./icon/error.png");
    }
    &.v-icon-warning {
      background-image: url("./icon/warning.png");
    }
    &.v-icon-success {
      background-image: url("./icon/success.png");
    }
    &.v-icon-close {
      position: absolute;
      top: 50%;
      right: 15px;
      transform: translateY(-50%);
      cursor: pointer;
      &::before,
      &::after {
        position: absolute;
        top: 50%;
        left: 50%;
        content: "";
        display: block;
        width: 70%;
        height: 1px;
        background: #666;
      }
      &::before {
        transform: translate(-50%, -50%) rotate(45deg);
      }
      &::after {
        transform: translate(-50%, -50%) rotate(-45deg);
      }
    }
  }
  .v-message__content {
    max-width: 500px;
    margin-left: 10px;
    flex: 1;
    word-break: break-all;
  }
}
.v-message-fade-enter,
.v-message-fade-leave-active {
  opacity: 0;
  transform: translate(-50%, -100%);
}
</style>
